/*
 * Copyright (C) Francisco Morero Peyrona. All rights reserved.
 *
 * This software is published under the terms of Open Source
 * License version 1.1, a copy of which has been included with this
 * distribution in the License.txt file.
 */

package jdbcmanager.print;

import java.awt.*;
import java.awt.print.*;

import javax.swing.*;

/**
 * Some printing usefull functions.
 * 
 * @author Francisco Morero Peyrona
 */

public final class PrintTools
{
   /**
    * Prints passed <code>JComponent</code> into passed <code>Graphics</code> context.
    * <p>
    * It is a very convenient function to be called by components that implement 
    * <code>Printable</code> interface.  
    * <p>
    * In case that the component requieres more than one page, it is divided into as 
    * necessary areas as needed, each one of the areas has the size of a page.
    * Pages are printed from left to right and from top to bottom.<br> 
    * Like this:<br>
    * <pre>
    * [ 0 ][ 1 ][ 2 ][ 3 ]
    * [ 4 ][ 5 ][ 6 ][ 7 ]
    * [ 8 ][ 9 ][...][...]
    * </pre>
    *  
    * @param source JComponent instance to be printed
    * @param g      Graphics context to print into
    * @param pf     PageFormat to be used
    * @param nPg    Page number to be printed (zero based)
    * @return       <code>Printable.PAGE_EXISTS</code> if the component has enought size or
    *               <code>Printable.NO_SUCH_PAGE</code> when there are no more pages to be printed.
    * @throws PrinterException If something goes wrong
    */
   public static int print( JComponent source, Graphics g, PageFormat pf, int nPg ) 
   {
      double nPrnWidth  = Math.round( pf.getImageableWidth()  );         // Printable width  area
      double nPrnHeight = Math.round( pf.getImageableHeight() );         // Printable height area                                        
      double nHorzPages = Math.ceil( source.getWidth()  / nPrnWidth  );  // Total number of horizontal pages (columns) 
      double nVertPages = Math.ceil( source.getHeight() / nPrnHeight );  // Total number of vertical   pages (rows)
      
      if( nPg < nHorzPages * nVertPages )
      {
         int nRow = (int) Math.ceil( (nPg + 1) / nHorzPages ) - 1;   // -1 == zero based
         int nCol = (int) ((nPg) % nHorzPages);                      // zero based
         int nX   = (int) (nCol * nPrnWidth);
         int nY   = (int) (nRow * nPrnHeight);
       
         Graphics2D g2 = (Graphics2D) g;
                    g2.translate( pf.getImageableX() - nX, pf.getImageableY() - nY );
                    g2.setClip( nX, nY, (int) nPrnWidth, (int) nPrnHeight );      
         
         // paint( Graphics g ) does not work fine if DoubleBuffered is enabled         
         boolean bDoubleBuffer = source.isDoubleBuffered();
         source.setDoubleBuffered( false ); 
         source.paint( g2 );
         source.setDoubleBuffered( bDoubleBuffer );
         
         return Printable.PAGE_EXISTS;
      }
      
      return Printable.NO_SUCH_PAGE;
   }
}